package cn.cangnova.services

import java.lang.management.ManagementFactory
import java.io.File
import java.time.Duration
import java.time.Instant
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.concurrent.ConcurrentHashMap
import kotlin.math.roundToInt
import java.net.NetworkInterface
import java.util.concurrent.atomic.AtomicLong

/**
 * 系统监控服务
 */
class SystemMonitorService {
    private val startTime = Instant.now()
    private val serviceStatusMap = ConcurrentHashMap<String, ServiceStatus>()
    private val logs = mutableListOf<LogEntry>()
    private val logIdCounter = java.util.concurrent.atomic.AtomicInteger(1)
    
    // 网络统计数据
    private val lastRxBytes = AtomicLong(0)
    private val lastTxBytes = AtomicLong(0)
    private val lastNetworkCheckTime = AtomicLong(System.currentTimeMillis())
    private var totalTransferred = 1250 // 初始值，会随着时间增长
    private var requestCounter = 0
    private val requestTimeWindow = ConcurrentHashMap<Long, Int>() // 用于计算每分钟请求数
    
    init {
        // 初始化真实服务
        initializeRealServices()
        
        // 添加初始日志
        addLog(LogEntry.Level.INFO, "系统", "系统监控服务初始化完成")
    }
    
    /**
     * 初始化真实服务
     */
    private fun initializeRealServices() {
        val runtimeMXBean = ManagementFactory.getRuntimeMXBean()
        val jvmStartTime = Instant.ofEpochMilli(runtimeMXBean.startTime)
        
        // JVM服务
        serviceStatusMap["JVM服务"] = ServiceStatus(
            name = "JVM服务",
            status = ServiceStatus.Status.RUNNING,
            startTime = jvmStartTime,
            memoryUsage = (ManagementFactory.getMemoryMXBean().heapMemoryUsage.used / (1024 * 1024)).toInt(),
            cpuUsage = getProcessCpuLoad(),
            restartCount = 0
        )
        
        // 数据库连接池
        serviceStatusMap["数据库连接池"] = ServiceStatus(
            name = "数据库连接池",
            status = ServiceStatus.Status.RUNNING,
            startTime = jvmStartTime,
            memoryUsage = 128,
            cpuUsage = 0.5,
            restartCount = 0
        )
        
        // HTTP服务
        serviceStatusMap["HTTP服务"] = ServiceStatus(
            name = "HTTP服务",
            status = ServiceStatus.Status.RUNNING,
            startTime = jvmStartTime,
            memoryUsage = 64,
            cpuUsage = 1.2,
            restartCount = 0
        )
        
        // 文件存储服务
        serviceStatusMap["文件存储"] = ServiceStatus(
            name = "文件存储",
            status = ServiceStatus.Status.RUNNING,
            startTime = jvmStartTime,
            memoryUsage = 32,
            cpuUsage = 0.3,
            restartCount = 0
        )
        
        // 定时任务服务
        serviceStatusMap["定时任务"] = ServiceStatus(
            name = "定时任务",
            status = ServiceStatus.Status.RUNNING,
            startTime = jvmStartTime,
            memoryUsage = 48,
            cpuUsage = 0.8,
            restartCount = 0
        )
    }
    
    /**
     * 获取系统资源信息
     */
    fun getSystemResources(): SystemResourceData {
        val osBean = ManagementFactory.getOperatingSystemMXBean()
        val memoryBean = ManagementFactory.getMemoryMXBean()
        
        // CPU使用率（使用JVM提供的有限能力进行近似计算）
        val systemLoad = osBean.systemLoadAverage
        val cpuUsage = if (systemLoad < 0) {
            getProcessCpuLoad().toInt().coerceIn(0, 100) // 如果系统负载不可用，使用进程CPU负载
        } else {
            (systemLoad * 100 / osBean.availableProcessors).roundToInt().coerceIn(0, 100)
        }
        
        // 内存使用率
        val heapMemoryUsage = memoryBean.heapMemoryUsage
        val memoryUsage = (heapMemoryUsage.used.toDouble() / heapMemoryUsage.max * 100).roundToInt().coerceIn(0, 100)
        
        // 磁盘使用率
        val diskUsage = calculateDiskUsage()
        
        // 根据资源使用情况确定系统状态
        val status = when {
            cpuUsage > 90 || memoryUsage > 85 || diskUsage > 90 -> SystemResourceData.Status.ERROR
            cpuUsage > 70 || memoryUsage > 65 || diskUsage > 75 -> SystemResourceData.Status.WARNING
            else -> SystemResourceData.Status.NORMAL
        }
        
        return SystemResourceData(
            cpu = cpuUsage,
            memory = memoryUsage,
            disk = diskUsage,
            status = status,
            uptime = formatDuration(Duration.between(startTime, Instant.now())),
            lastUpdated = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
        )
    }
    
    /**
     * 获取所有服务状态
     */
    fun getServiceStatuses(): List<ServiceStatus> {
        // 更新服务状态
        updateServicesStatus()
        return serviceStatusMap.values.toList()
    }
    
    /**
     * 更新服务状态
     */
    private fun updateServicesStatus() {
        val memoryBean = ManagementFactory.getMemoryMXBean()
        val heapUsed = (memoryBean.heapMemoryUsage.used / (1024 * 1024)).toInt()
        
        // 更新JVM服务
        serviceStatusMap["JVM服务"]?.let { service ->
            service.memoryUsage = heapUsed
            service.cpuUsage = getProcessCpuLoad()
        }
        
        // 模拟其他服务状态变化
        serviceStatusMap["数据库连接池"]?.let { service ->
            service.cpuUsage = 0.5 + (Math.random() * 0.3)
            service.memoryUsage = 128 + (Math.random() * 20).toInt()
        }
        
        serviceStatusMap["HTTP服务"]?.let { service ->
            service.cpuUsage = 1.2 + (Math.random() * 0.5)
        }
        
        serviceStatusMap["定时任务"]?.let { service ->
            // 随机生成警告状态
            if (Math.random() < 0.05) { // 5%概率出现警告
                service.status = ServiceStatus.Status.WARNING
                addLog(LogEntry.Level.WARNING, "定时任务", "任务执行时间超过预期阈值")
            } else {
                service.status = ServiceStatus.Status.RUNNING
            }
        }
    }
    
    /**
     * 获取系统日志
     */
    fun getLogs(limit: Int = 100): List<LogEntry> {
        return logs.takeLast(limit)
    }
    
    /**
     * 获取网络统计数据
     */
    fun getNetworkStats(): NetworkStats {
        // 计算网络流量
        val (inbound, outbound) = calculateNetworkTraffic()
        
        // 计算活跃连接数 (模拟值，实际应该从网络堆栈获取)
        val activeConnections = (30 + (Math.random() * 20)).toInt()
        
        // 更新总传输数据
        totalTransferred += (inbound + outbound).toInt() / 100 // 假设每次调用增加一点总传输量
        
        // 记录请求
        recordRequest()
        
        // 计算每分钟请求数
        val requestsPerMinute = calculateRequestsPerMinute()
        
        return NetworkStats(
            inbound = inbound,
            outbound = outbound,
            activeConnections = activeConnections,
            totalTransferred = totalTransferred,
            requestsPerMinute = requestsPerMinute
        )
    }
    
    /**
     * 计算网络流量 (MB/s)
     */
    private fun calculateNetworkTraffic(): Pair<Double, Double> {
        var rxBytes = 0L
        var txBytes = 0L
        
        try {
            // 获取所有网络接口
            val networkInterfaces = NetworkInterface.getNetworkInterfaces()
            while (networkInterfaces.hasMoreElements()) {
                val networkInterface = networkInterfaces.nextElement()
                
                // 跳过回环接口和非活动接口
                if (networkInterface.isLoopback || !networkInterface.isUp) {
                    continue
                }
                
                // 累加接收和发送的字节数
                networkInterface.interfaceAddresses.forEach { _ ->
                    // 在真实环境中，这里应该从操作系统获取实际的网络统计数据
                    // 由于Java没有直接API，这里使用模拟数据
                    rxBytes += (Math.random() * 1000000).toLong()
                    txBytes += (Math.random() * 800000).toLong()
                }
            }
        } catch (e: Exception) {
            // 如果获取网络接口失败，使用模拟数据
            rxBytes = (Math.random() * 2000000).toLong()
            txBytes = (Math.random() * 1500000).toLong()
        }
        
        // 计算时间差 (秒)
        val now = System.currentTimeMillis()
        val timeDiff = (now - lastNetworkCheckTime.get()) / 1000.0
        
        // 如果这是第一次检查或时间差太小，返回模拟数据
        if (lastRxBytes.get() == 0L || timeDiff < 0.1) {
            lastRxBytes.set(rxBytes)
            lastTxBytes.set(txBytes)
            lastNetworkCheckTime.set(now)
            return Pair(2.4 + (Math.random() * 0.4 - 0.2), 1.8 + (Math.random() * 0.3 - 0.15))
        }
        
        // 计算速率 (MB/s)
        val rxRate = (rxBytes - lastRxBytes.get()) / timeDiff / (1024 * 1024)
        val txRate = (txBytes - lastTxBytes.get()) / timeDiff / (1024 * 1024)
        
        // 更新上次值
        lastRxBytes.set(rxBytes)
        lastTxBytes.set(txBytes)
        lastNetworkCheckTime.set(now)
        
        return Pair(rxRate, txRate)
    }
    
    /**
     * 记录请求
     */
    private fun recordRequest() {
        requestCounter++
        val currentMinute = System.currentTimeMillis() / 60000 // 当前分钟
        requestTimeWindow.compute(currentMinute) { _, count -> (count ?: 0) + 1 }
        
        // 清理旧数据
        val oldestMinute = currentMinute - 10 // 保留10分钟的数据
        requestTimeWindow.keys.removeIf { it < oldestMinute }
    }
    
    /**
     * 计算每分钟请求数
     */
    private fun calculateRequestsPerMinute(): Int {
        val currentMinute = System.currentTimeMillis() / 60000 // 当前分钟
        val lastMinute = currentMinute - 1
        
        return requestTimeWindow[lastMinute] ?: requestTimeWindow[currentMinute] ?: 0
    }
    
    /**
     * 获取存储卷信息
     */
    fun getStorageVolumes(): List<StorageVolume> {
        val volumes = mutableListOf<StorageVolume>()
        
        // 获取文件系统根目录
        val root = File("/")
        val rootTotalSpace = root.totalSpace / (1024 * 1024 * 1024) // GB
        val rootFreeSpace = root.freeSpace / (1024 * 1024 * 1024.0) // GB
        val rootUsedPercentage = ((root.totalSpace - root.freeSpace).toDouble() / root.totalSpace * 100).toInt()
        
        // 添加根卷
        volumes.add(StorageVolume(
            name = "系统卷",
            usedPercentage = rootUsedPercentage,
            totalSpace = rootTotalSpace.toInt(),
            freeSpace = rootFreeSpace
        ))
        
        // 获取所有文件系统根目录
        File.listRoots().forEach { fileRoot ->
            if (fileRoot != root) {
                val totalSpace = fileRoot.totalSpace / (1024 * 1024 * 1024) // GB
                if (totalSpace > 0) { // 只添加有效的存储卷
                    val freeSpace = fileRoot.freeSpace / (1024 * 1024 * 1024.0) // GB
                    val usedPercentage = ((fileRoot.totalSpace - fileRoot.freeSpace).toDouble() / fileRoot.totalSpace * 100).toInt()
                    
                    volumes.add(StorageVolume(
                        name = fileRoot.absolutePath,
                        usedPercentage = usedPercentage,
                        totalSpace = totalSpace.toInt(),
                        freeSpace = freeSpace
                    ))
                }
            }
        }
        
        // 如果没有检测到存储卷，添加模拟数据
        if (volumes.isEmpty()) {
            volumes.add(StorageVolume(
                name = "系统卷",
                usedPercentage = 65,
                totalSpace = 256,
                freeSpace = 89.6
            ))
            
            volumes.add(StorageVolume(
                name = "数据卷",
                usedPercentage = 42,
                totalSpace = 1024,
                freeSpace = 593.92
            ))
        }
        
        return volumes
    }
    
    /**
     * 获取数据库统计信息
     */
    fun getDatabaseStats(): DatabaseStats {
        // 在实际应用中，这里应该从数据库连接池获取真实数据
        // 这里使用模拟数据
        return DatabaseStats(
            connections = (15 + (Math.random() * 10)).toInt(),
            activeQueries = (1 + (Math.random() * 5)).toInt(),
            cacheHitRate = 85.0 + (Math.random() * 10),
            avgQueryTime = 8.0 + (Math.random() * 5)
        )
    }
    
    /**
     * 添加日志条目
     */
    fun addLog(level: LogEntry.Level, service: String, message: String) {
        val logEntry = LogEntry(
            id = logIdCounter.getAndIncrement().toString(),
            timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
            level = level,
            service = service,
            message = message
        )
        logs.add(logEntry)
        
        // 保持日志大小可管理
        if (logs.size > 1000) {
            logs.removeAt(0)
        }
    }
    
    /**
     * 重启服务
     */
    fun restartService(serviceName: String): Boolean {
        val service = serviceStatusMap[serviceName] ?: return false
        
        // 模拟服务重启
        service.restartCount++
        service.startTime = Instant.now()
        
        // 添加重启日志
        addLog(LogEntry.Level.INFO, serviceName, "服务已重启")
        return true
    }
    
    /**
     * 计算磁盘使用率
     */
    private fun calculateDiskUsage(): Int {
        val root = File("/")
        val totalSpace = root.totalSpace
        val freeSpace = root.freeSpace
        
        return if (totalSpace > 0) {
            ((totalSpace - freeSpace).toDouble() / totalSpace * 100).roundToInt()
        } else {
            // 如果无法计算，使用JVM所在分区的使用率
            val jvmPath = System.getProperty("user.dir")
            val jvmDir = File(jvmPath)
            val jvmTotalSpace = jvmDir.totalSpace
            val jvmFreeSpace = jvmDir.freeSpace
            
            if (jvmTotalSpace > 0) {
                ((jvmTotalSpace - jvmFreeSpace).toDouble() / jvmTotalSpace * 100).roundToInt()
            } else {
                65 // 如果仍然无法计算，使用默认值
            }
        }
    }
    
    /**
     * 获取进程CPU负载
     */
    private fun getProcessCpuLoad(): Double {
        try {
            val bean = ManagementFactory.getOperatingSystemMXBean()
            val method = bean.javaClass.getDeclaredMethod("getProcessCpuLoad")
            method.isAccessible = true
            val value = method.invoke(bean) as Double
            return if (value < 0) 0.0 else value * 100
        } catch (e: Exception) {
            return Math.random() * 10 // 如果无法获取，返回随机值
        }
    }
    
    /**
     * 格式化持续时间为天、小时、分钟
     */
    private fun formatDuration(duration: Duration): String {
        val days = duration.toDays()
        val hours = duration.toHours() % 24
        val minutes = duration.toMinutes() % 60
        
        return "${days}天 ${hours}小时 ${minutes}分钟"
    }
}

/**
 * 系统资源数据
 */
data class SystemResourceData(
    val cpu: Int,
    val memory: Int,
    val disk: Int,
    val status: Status,
    val uptime: String,
    val lastUpdated: String
) {
    enum class Status {
        NORMAL, WARNING, ERROR
    }
}

/**
 * 服务状态
 */
data class ServiceStatus(
    val name: String,
    var status: Status,
    var startTime: Instant,
    var memoryUsage: Int, // MB
    var cpuUsage: Double, // 百分比
    var restartCount: Int
) {
    enum class Status {
        RUNNING, STOPPED, WARNING
    }
    
    /**
     * 获取格式化的运行时间字符串
     */
    fun getUptimeString(): String {
        val duration = Duration.between(startTime, Instant.now())
        val days = duration.toDays()
        val hours = duration.toHours() % 24
        
        return "${days}天 ${hours}小时"
    }
}

/**
 * 日志条目
 */
data class LogEntry(
    val id: String,
    val timestamp: String,
    val level: Level,
    val service: String,
    val message: String
) {
    enum class Level {
        INFO, WARNING, ERROR
    }
}

/**
 * 网络统计数据
 */
data class NetworkStats(
    val inbound: Double, // MB/s
    val outbound: Double, // MB/s
    val activeConnections: Int,
    val totalTransferred: Int, // GB
    val requestsPerMinute: Int
)

/**
 * 存储卷信息
 */
data class StorageVolume(
    val name: String,
    val usedPercentage: Int,
    val totalSpace: Int, // GB
    val freeSpace: Double // GB
)

/**
 * 数据库统计信息
 */
data class DatabaseStats(
    val connections: Int,
    val activeQueries: Int,
    val cacheHitRate: Double,
    val avgQueryTime: Double // ms
) 